package com.idudiao.sc.neo4j.utils;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.ToIntFunction;

/**
 * @author: 读钓
 * @date 2019-01-28 上午 12:56
 */
public class MethodReferenceUtils {

    public static <T> Method getReferencedMethod(Class<T> clazz, ToIntFunction<T> methodRef) {
        // 创建一个 Enhancer，并配置拦截器
        AtomicReference<Method> ref = new AtomicReference<Method>();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                ref.set(method);
                Object result = proxy.invokeSuper(obj, args);
                return result;
            }
        });

        // 创建一个实例
        @SuppressWarnings("unchecked")
        T phantom = (T) enhancer.create();

        // 在实例上调用 MethodReference
        methodRef.applyAsInt(phantom);

        Method method = ref.get();
        if (method == null) {
            // 如果传入的不是方法引用，而是直接 new 出来的 Function 实例，那么 method 就会是 null
            throw new IllegalArgumentException(String.format("Invalid method reference on class [%s]", clazz));
        }
        System.out.println(method);
        return method;
    }
}